package controller;

import model.OnScreen;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class OrientationManager implements SensorEventListener 
{
	private Context _context;
	private SensorManager _sensorManager; 
	
	private Sensor _accelerometer;
	private Sensor _magnetometer;                     
	
	private float[] _gravity;
	private float[] _geomagnetic;
	
	public OrientationManager(Context context)
	{
		this._context = context;
	}

	// initialize Orientation Manager
	public void init() 
	{
		_sensorManager = (SensorManager) _context.getSystemService(Context.SENSOR_SERVICE);
		
		_accelerometer	 = 	_sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		_magnetometer	 = 	_sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
		 
	}
	
	protected void onResume() 
	{
		_sensorManager.registerListener(this, _accelerometer, SensorManager.SENSOR_DELAY_UI);
		_sensorManager.registerListener(this, _magnetometer, SensorManager.SENSOR_DELAY_UI);
	}
	
	protected void onPause() 
	{
		// delete the orientation from OnScreen
		OnScreen.getInstance().setOrientation(null);
		_sensorManager.unregisterListener(this);
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) 
	{
		// Do nothing.
	}

	@Override
	public void onSensorChanged(SensorEvent event) 
	{
		if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
			_gravity = event.values;
		if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
			_geomagnetic = event.values;
		if (_gravity != null && _geomagnetic != null) 
		{
			float R[] = new float[9];
			float I[] = new float[9];
			/*Computes the inclination matrix I as well as the rotation matrix R transforming a vector from the device coordinate
			 *  system to the world's coordinate system which is defined as a direct orthonormal basis*/
			boolean success = SensorManager.getRotationMatrix(R, I, _gravity, _geomagnetic);
			if (success) 
			{
				float orientation[] = new float[3];
				/*Computes the device's orientation based on the rotation matrix*/
				SensorManager.getOrientation(R, orientation);
				
				// change orientation array to degrees array
				orientation[0] = (float) Math.toDegrees(orientation[0]);
				orientation[1] = (float) Math.toDegrees(orientation[1]);
				orientation[2] = (float) Math.toDegrees(orientation[2]);
				
				OnScreen.getInstance().updateOrientation(orientation);
			}
		}
	 }
	
}
